package com.afs.electronicforensics.utils;
import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.afs.electronicforensics.activity.R;
import com.afs.electronicforensics.activity.ShowActivity;
import com.afs.electronicforensics.config.MyOSSconfig;
import com.afs.electronicforensics.entity.Result;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.common.utils.IOUtils;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.CompleteMultipartUploadRequest;
import com.alibaba.sdk.android.oss.model.CompleteMultipartUploadResult;
import com.alibaba.sdk.android.oss.model.DeleteObjectResult;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.InitiateMultipartUploadRequest;
import com.alibaba.sdk.android.oss.model.InitiateMultipartUploadResult;
import com.alibaba.sdk.android.oss.model.ListPartsRequest;
import com.alibaba.sdk.android.oss.model.ListPartsResult;
import com.alibaba.sdk.android.oss.model.PartETag;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.alibaba.sdk.android.oss.model.UploadPartRequest;
import com.alibaba.sdk.android.oss.model.UploadPartResult;
import com.bumptech.glide.Glide;
import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * Created by Administrator on 2017/3/1.
 */

public class OssManager {
    private OSS oss;
    private String type = null;
    private String newUrl;


    public static OssManager getInstance() {
        return OssInstance.instance;
    }

    private static class OssInstance {
        private static final OssManager instance = new OssManager();
    }

    private OssManager() {
    }

    private String bucketName;

    /**
     * 初始化
     **/
    public OssManager init(Context context) {
        if (oss == null) {
            OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(MyOSSconfig.OSS_ACCESS_KEY_ID, MyOSSconfig.OSS_ACCESS_KEY_SECRET);
            oss = new OSSClient(context, MyOSSconfig.OSS_EXTERNAL_ENDPOINT, credentialProvider);
        }
        this.bucketName = MyOSSconfig.BUCKET_NAME;
        return OssInstance.instance;
    }

    OSSAsyncTask task;

    public void uploadOss(String name, String filePath, String upName, String content) {
        Log.d("name", name + ":" + filePath);
        //获取文件后缀名
        String substring = filePath.substring(filePath.lastIndexOf(".") + 1);
        int type = FileTypeUtil.getType(substring);
        //使用uuid作为文件名防止重复
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String newName = name + "." + substring;
        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(bucketName, "upload/" + newName, filePath);
        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
            }
        });
        task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.d("PutObject", "UploadSuccess");
                UploadAdd uploadAdd = new UploadAdd(newName, type, upName, content);
                uploadAdd.execute(null, null, null);


            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                }

            }
        });
        // task.cancel(); // 可以取消任务
        // task.waitUntilFinished(); // 可以等待直到任务完成
    }

    public void uploadHead(String name, String filePath, String username) {
        Log.d("name", name + ":" + filePath);
        //获取文件后缀名
        String substring = filePath.substring(filePath.lastIndexOf(".") + 1);
        int type = FileTypeUtil.getType(substring);
        //使用uuid作为文件名防止重复
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String newname = uuid + "." + substring;
        /*String newname = filePath.substring(filePath.lastIndexOf("/")+1);*/
        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(bucketName, "head/" + newname, filePath);

        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
            }
        });
        task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.d("PutObject", "UploadSuccess");
                UploadHead uploadHead = new UploadHead(newname, username);
                uploadHead.execute();
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                }
            }
        });
        // task.cancel(); // 可以取消任务

        // task.waitUntilFinished(); // 可以等待直到任务完成
    }

    /**
     * 阿里云OSS上传（默认是异步多文件上传）
     *
     * @param urls
     */
    public void MutipartUpload(final List<String> urls) {

        if (urls.size() <= 0) {
            // 文件全部上传完毕，这里编写上传结束的逻辑，如果要在主线程操作，最好用Handler或runOnUiThead做对应逻辑
            return;// 这个return必须有，否则下面报越界异常，原因自己思考下哈
        }
        final String url = urls.get(0);
        if (TextUtils.isEmpty(url)) {
            urls.remove(0);
            // url为空就没必要上传了，这里做的是跳过它继续上传的逻辑。
            MutipartUpload(urls);
            return;
        }

        File file = new File(url);
        if (null == file || !file.exists()) {
            urls.remove(0);
            // 文件为空或不存在就没必要上传了，这里做的是跳过它继续上传的逻辑。
            MutipartUpload(urls);
            return;
        }
        // 文件后缀
        String fileSuffix = "";
        if (file.isFile()) {
            // 获取文件后缀名
            fileSuffix = file.getName().substring(file.getName().lastIndexOf("."));
        }
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String newname = uuid + "." + fileSuffix;
        // 文件标识符objectKey
        final String objectKey = "upload/" + newname;
        // 下面3个参数依次为bucket名，ObjectKey名，上传文件路径
        PutObjectRequest put = new PutObjectRequest(MyOSSconfig.BUCKET_NAME, objectKey, url);

        // 设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                // 进度逻辑
            }
        });
        // 异步上传
        OSSAsyncTask task = oss.asyncPutObject(put,
                new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                    @Override
                    public void onSuccess(PutObjectRequest request, PutObjectResult result) { // 上传成功
                        urls.remove(0);
                        MutipartUpload(urls);// 递归同步效果
                    }

                    @Override
                    public void onFailure(PutObjectRequest request, ClientException clientExcepion,
                                          ServiceException serviceException) { // 上传失败

                        // 请求异常
                        if (clientExcepion != null) {
                            // 本地异常如网络异常等
                            clientExcepion.printStackTrace();
                        }
                        if (serviceException != null) {
                            // 服务异常
                            Log.e("ErrorCode", serviceException.getErrorCode());
                            Log.e("RequestId", serviceException.getRequestId());
                            Log.e("HostId", serviceException.getHostId());
                            Log.e("RawMessage", serviceException.getRawMessage());
                        }
                    }
                });
        // task.cancel(); // 可以取消任务
        // task.waitUntilFinished(); // 可以等待直到任务完成
    }

    /**
     * 分片上传
     **/
    public void pullFP(String filePath, String name) throws ClientException, ServiceException {
        String uploadId;
        InitiateMultipartUploadRequest init = new InitiateMultipartUploadRequest(bucketName, name);
        InitiateMultipartUploadResult initResult = oss.initMultipartUpload(init);
        uploadId = initResult.getUploadId();
        long partSize = 128 * 1024; // 设置分片大小
        int currentIndex = 1; // 上传分片编号，从1开始

        File uploadFile = new File(filePath); // 需要分片上传的文件

        InputStream input = null;
        try {
            input = new FileInputStream(uploadFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        long fileLength = uploadFile.length();
        long uploadedLength = 0;
        List<PartETag> partETags = new ArrayList<PartETag>(); // 保存分片上传的结果
        while (uploadedLength < fileLength) {
            int partLength = (int) Math.min(partSize, fileLength - uploadedLength);
            byte[] partData = new byte[0]; // 按照分片大小读取文件的一段内容
            try {
                partData = IOUtils.readStreamAsBytesArray(input, partLength);
            } catch (IOException e) {
                e.printStackTrace();
            }
            UploadPartRequest uploadPart = new UploadPartRequest(bucketName, name, uploadId, currentIndex);
            uploadPart.setPartContent(partData); // 设置分片内容
            UploadPartResult uploadPartResult = null;
            try {
                uploadPartResult = oss.uploadPart(uploadPart);
            } catch (ClientException e) {
                e.printStackTrace();
            } catch (ServiceException e) {
                e.printStackTrace();
            }
            partETags.add(new PartETag(currentIndex, uploadPartResult.getETag())); // 保存分片上传成功后的结果
            uploadedLength += partLength;
            currentIndex++;
            Log.d("currentIndex", currentIndex + "");
        }

        CompleteMultipartUploadRequest complete = new CompleteMultipartUploadRequest(bucketName, name, uploadId, partETags);
        final CompleteMultipartUploadResult completeResult = oss.completeMultipartUpload(complete);
        complete.setCallbackParam(new HashMap<String, String>() {
            {

                Log.d("uploadEnd", "uploadEnd");
                Log.d("multipartUpload", "multipart upload success! Location: " + completeResult.getLocation());
                put("callbackUrl", "<server address>");
                put("callbackBody", "<test>");
            }
        });

        ListPartsRequest listParts = new ListPartsRequest(bucketName, name, uploadId);

        ListPartsResult result = oss.listParts(listParts);

        for (int i = 0; i < result.getParts().size(); i++) {
            Log.d("已上传分片", "partNum: " + result.getParts().get(i).getPartNumber());
            Log.d("已上传分片", "partEtag: " + result.getParts().get(i).getETag());
            Log.d("已上传分片", "lastModified: " + result.getParts().get(i).getLastModified());
            Log.d("已上传分片", "partSize: " + result.getParts().get(i).getSize());
        }

    }

    public void download(String filename,String url, final String path) {
        newUrl = "upload/" + filename;
        GetObjectRequest get = new GetObjectRequest(bucketName, newUrl);
        //设置下载进度回调
        get.setProgressListener(new OSSProgressCallback<GetObjectRequest>() {
            @Override
            public void onProgress(GetObjectRequest request, long currentSize, long totalSize) {
                OSSLog.logDebug("getobj_progress: " + currentSize + "  total_size: " + totalSize, false);
                Log.e("zzz", "HelloMoonFragment--onProgress--currentSize" + currentSize + ",totalSize--" + totalSize);
            }
        });
        OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                Log.e("zzz", "HelloMoonFragment--onSuccess--");
                // 请求成功
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    String realpath = null;
                    if (2 == FileTypeUtil.getType(newUrl.substring(newUrl.lastIndexOf(".") + 1))) {
                        type = Constants.USER_PATH.getImagePath();
                    }
                    if (3 == FileTypeUtil.getType(newUrl.substring(newUrl.lastIndexOf(".") + 1))) {
                        type = Constants.USER_PATH.getAudioPath();
                    }
                    if (1 == FileTypeUtil.getType(newUrl.substring(newUrl.lastIndexOf(".") + 1))) {
                        type = Constants.USER_PATH.getVideoPath();
                    }
                    realpath = path + type;
                    is = result.getObjectContent();
                    File file = new File(realpath + filename);
                    if (!file.exists()) {
                        file.getParentFile().mkdirs();
                        file.createNewFile();

                    }
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    fos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (is != null) {
                        try {
                            is.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    Log.e("zzz", "HelloMoonFragment--ErrorCode--clientException" + clientExcepion.getMessage());
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("zzz", "HelloMoonFragment--ErrorCode--" + serviceException.getErrorCode());
                    Log.e("zzz", "HelloMoonFragment--RequestId--" + serviceException.getRequestId());
                    Log.e("zzz", "HelloMoonFragment--HostId--" + serviceException.getHostId());
                    Log.e("zzz", "HelloMoonFragment--RawMessage--" + serviceException.getRawMessage());
                }
            }
        });
    }

    public void delete(String name,int type,String userid){
         new SoftDelete(name,type,userid).execute();
    }

    public void Mutipartdownload(final List<String> urls, final String path) {
        if (urls.size() <= 0) {
            // 文件全部上传完毕，这里编写上传结束的逻辑，如果要在主线程操作，最好用Handler或runOnUiThead做对应逻辑
            return;// 这个return必须有，否则下面报越界异常，原因自己思考下哈
        }
        final String url = urls.get(0);
        if (TextUtils.isEmpty(url)) {
            urls.remove(0);
            // url为空就没必要下载了，这里做的是跳过它继续上传的逻辑。
            Mutipartdownload(urls, path);
            return;
        }

        File file = new File(url);
        if (null == file || file.exists()) {
            urls.remove(0);
            // 文件为空或不存在就没必要下载了，这里做的是跳过它继续上传的逻辑。
            Mutipartdownload(urls, path);
            return;
        }
        GetObjectRequest get = new GetObjectRequest(bucketName, url);
        String filename = url.substring(url.indexOf("/"));
        //设置下载进度回调
        get.setProgressListener(new OSSProgressCallback<GetObjectRequest>() {
            @Override
            public void onProgress(GetObjectRequest request, long currentSize, long totalSize) {
                OSSLog.logDebug("getobj_progress: " + currentSize + "  total_size: " + totalSize, false);
                Log.e("zzz", "HelloMoonFragment--onProgress--currentSize" + currentSize + ",totalSize--" + totalSize);
            }
        });
        OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                Log.e("zzz", "HelloMoonFragment--onSuccess--");
                // 请求成功
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    String realpath = null;
                    realpath = path + "电子取证";
                    is = result.getObjectContent();
                    File file = new File(realpath + filename);
                    if (!file.exists()) {
                        file.getParentFile().mkdirs();
                        file.createNewFile();

                    }
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    fos.flush();
                    urls.remove(0);
                    // 文件为空或不存在就没必要下载了，这里做的是跳过它继续上传的逻辑。
                    Mutipartdownload(urls, path);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (is != null) {
                        try {
                            is.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    Log.e("zzz", "HelloMoonFragment--ErrorCode--clientException" + clientExcepion.getMessage());
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("zzz", "HelloMoonFragment--ErrorCode--" + serviceException.getErrorCode());
                    Log.e("zzz", "HelloMoonFragment--RequestId--" + serviceException.getRequestId());
                    Log.e("zzz", "HelloMoonFragment--HostId--" + serviceException.getHostId());
                    Log.e("zzz", "HelloMoonFragment--RawMessage--" + serviceException.getRawMessage());
                }
            }
        });
    }

    private class UploadAdd extends AsyncTask {
        private String name;
        private String upName;
        private int filetype;
        private String content;

        public UploadAdd(String name, int filetype, String upName, String content) {
            this.name = name;
            this.filetype = filetype;
            this.upName = upName;
            this.content = content;
        }

        @Override
        protected Object doInBackground(Object[] params) {
            String mUrl = null;
            mUrl = Constants.URL_ROOT + "file/upLoadAdd?" + "content=" + content + "&filename=" + name + "&type=" + filetype + "&upName=" + upName + "&url=upload/" + name;
            try {
                URL url = new URL(mUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");//设置请求方式为get
                conn.setConnectTimeout(5000);
                System.out.println(url);
                if (conn.getResponseCode() == 200) {
                    InputStream is = conn.getInputStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    String str = br.readLine();
                    return str;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

    }

    private class UploadHead extends AsyncTask {
            private String name;
            private String username;

            public UploadHead(String name, String username) {
                this.name = name;
                this.username = username;
            }

            @Override
            protected Object doInBackground(Object[] objects) {
                String mUrl = null;
                mUrl = "http://106.14.106.83:8081/user/updateForAndroid?" + "filePath=head/" + name + "&userName=" + username;
                try {
                    URL url = new URL(mUrl);
                    System.out.println(url);
                    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
                    urlConn.setRequestMethod("POST");//设置请求方式为get
                    urlConn.setDoInput(true);
                    urlConn.setDoOutput(true);
                    urlConn.setUseCaches(false);
                    urlConn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
                    urlConn.connect();
                    int responseCode = urlConn.getResponseCode();
                    System.out.println(responseCode);
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        InputStream stream = null;
                        try {
                            stream = urlConn.getInputStream();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        BufferedReader bufferedReader = null;
                        try {
                            bufferedReader = new BufferedReader(new InputStreamReader(stream,
                                    "UTf-8"));
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        String sread = null;
                        StringBuffer buffer = new StringBuffer();
                        while (true) {
                            try {
                                if (!((sread = bufferedReader.readLine()) != null)) break;
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            buffer.append(sread);
                            buffer.append("\r\n");
                        }
                        String string = buffer.toString();
                        if (string != null && string.startsWith("\ufeff")) {
                            string = string.substring(1);
                        }
                        Gson gson = new Gson();
                        Result result = gson.fromJson(string, Result.class);
                        return result;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }

        }

    private class SoftDelete extends AsyncTask {
        private String name;
        private int type;
        private String userid;

        public SoftDelete(String name, int type, String userid) {
            this.name = name;
            this.type = type;
            this.userid = userid;
        }

        @Override
        protected Object doInBackground(Object[] params) {
            String mUrl = null;
            mUrl = Constants.URL_ROOT + "file/softDelete?" + "messageName=" + name + "&type=" + type  + "&userid=" + userid;
            try {
                System.out.println(mUrl);
                URL url = new URL(mUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");//设置请求方式为get
                conn.setConnectTimeout(5000);
                System.out.println(url);
                if (conn.getResponseCode() == 200) {
                    InputStream is = conn.getInputStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    String str = br.readLine();
                    return str;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

    }
    }
